﻿
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Net;
using System.Text;
using System.Threading.Tasks;
using System.IO;
using Zhang;
using System.Text.RegularExpressions;

namespace Zhang.Utils
{
    public class HttpHelper
    {
        /// <summary>
        /// 通过表单上传文件
        /// </summary>
        /// <param name="postFile">文件内容</param>
        /// <param name="dicParam">表单参数</param>
        /// <param name="postURL">文件接收URL</param>
        /// <returns></returns>
        public static string PostFile(HttpPostedFileBase postFile, Dictionary<string, string> dicParam, string postURL)
        {
            HttpWebRequest webRequest;    // 上传请求对象
            HttpWebResponse webResponse;
            MemoryStream fileStream;      // 存储要上传的内容
            Stream requestStream;
            string boundary, formdata, backContent;
            byte[] arrByte;

            postURL = postURL.Trim();

            // 写入其它表单参数
            if (dicParam != null && dicParam.Keys.Count > 0)
            {
                postURL += (postURL.IndexOf("?") > 0 ? "" : "?");

                foreach (string key in dicParam.Keys)
                {
                    postURL += (postURL.EndsWith("?") ? "" : "&");
                    postURL += key + "=" + HttpUtility.UrlEncode(dicParam[key]);
                }
            }

            backContent = "";
            webRequest = (HttpWebRequest)WebRequest.Create(postURL);
            fileStream = new MemoryStream();

            boundary = "----" + DateTime.Now.Ticks.ToString("x");
            webRequest.Method = "POST";
            webRequest.Timeout = 10000;
            webRequest.ContentType = string.Format("multipart/form-data; boundary={0}", boundary);
            webRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8";
            webRequest.KeepAlive = true;
            webRequest.UserAgent = "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/31.0.1650.57 Safari/537.36";
            // 写入文件头部
            formdata = "\r\n--" + boundary + "\r\nContent-Disposition: form-data; name=\"file\"; filename=\"" + postFile.FileName + "\"\r\nContent-Type: application/octet-stream\r\n\r\n";
            arrByte = Encoding.UTF8.GetBytes(formdata);//第一行不需要换行
            fileStream.Write(arrByte, 0, arrByte.Length);
            // 写入文件内容
            arrByte = new byte[postFile.InputStream.Length];
            postFile.InputStream.Read(arrByte, 0, arrByte.Length);
            fileStream.Write(arrByte, 0, arrByte.Length);
            fileStream.Flush();
            // 文件内容结束分隔
            arrByte = Encoding.ASCII.GetBytes("\r\n--" + boundary + "--\r\n");
            fileStream.Write(arrByte, 0, arrByte.Length);

            webRequest.ContentLength = fileStream != null ? fileStream.Length : 0;

            if (fileStream != null)
            {
                fileStream.Position = 0;
                requestStream = webRequest.GetRequestStream();
                arrByte = new byte[fileStream.Length];
                fileStream.Read(arrByte, 0, arrByte.Length);
                requestStream.Write(arrByte, 0, arrByte.Length);
                fileStream.Close();//关闭文件访问
            }

            webResponse = (HttpWebResponse)webRequest.GetResponse();

            using (Stream responseStream = webResponse.GetResponseStream())
            {
                using (StreamReader myStreamReader = new StreamReader(responseStream, Encoding.GetEncoding("UTF-8")))
                {
                    backContent = myStreamReader.ReadToEnd();
                }
            }
            return backContent;
        }

        public static string HttpPost(string Url, string postDataStr, string contentType = "application/x-www-form-urlencoded")
        {
            byte[] postBytes = Encoding.GetEncoding("utf-8").GetBytes(postDataStr);
            HttpWebRequest request = WebRequest.Create(Url) as HttpWebRequest;//(HttpWebRequest)WebRequest.Create(Url);
            request.Method = "POST";
            request.ContentType = contentType;
            request.ContentLength = postBytes.Length;//Encoding.UTF8.GetByteCount(post_string);
            request.Timeout = 180000;
            // request.CookieContainer = cookie;

            Stream myRequestStream = request.GetRequestStream();

            myRequestStream.Write(postBytes, 0, postBytes.Length);
            myRequestStream.Close();

            HttpWebResponse response = (HttpWebResponse)request.GetResponse();

            Stream myResponseStream = response.GetResponseStream();
            StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
            string retString = myStreamReader.ReadToEnd();
            myStreamReader.Close();
            myResponseStream.Close();
            myStreamReader.Dispose();
            myResponseStream.Dispose();
            return retString;

        }

        public static string HttpGet(string Url, string contentType = "application/json;charset=UTF-8")
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
            request.Method = "GET";
            //request.ContentType = "text/html;charset=UTF-8";
            request.ContentType = contentType;
            request.Timeout = 180000;
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream myResponseStream = response.GetResponseStream();
            StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
            string retString = myStreamReader.ReadToEnd();
            myStreamReader.Close();
            myResponseStream.Close();
            myStreamReader.Dispose();
            myResponseStream.Dispose();

            return retString;
        }

        public static string HttpDelete(string Url)
        {
            return HttpRequest("DELETE", Url);
        }

        public static string HttpPut(string Url)
        {
            return HttpRequest("PUT", Url);
        }

        public static string HttpRequest(string method, string Url, string contentType = "application/json;charset=UTF-8")
        {
            HttpWebRequest request = (HttpWebRequest)WebRequest.Create(Url);
            request.Method = method;
            request.ContentType = contentType;
            request.Timeout = 180000;
            HttpWebResponse response = (HttpWebResponse)request.GetResponse();
            Stream myResponseStream = response.GetResponseStream();
            StreamReader myStreamReader = new StreamReader(myResponseStream, Encoding.GetEncoding("utf-8"));
            string retString = myStreamReader.ReadToEnd();
            myStreamReader.Close();
            myResponseStream.Close();
            myStreamReader.Dispose();
            myResponseStream.Dispose();

            return retString;
        }

         /// <summary>
        /// 压缩HTML,除去标签间的空格与tab等
        /// </summary>
        /// <param name="htmlContent"></param>
        /// <returns></returns>
        public static string Compression(string htmlContent)
        {
            htmlContent = Regex.Replace(htmlContent, @"<!--\S*?-->", string.Empty);
            htmlContent = Regex.Replace(htmlContent, @"^\s+", string.Empty);
            htmlContent = Regex.Replace(htmlContent, "\n", " ");
            htmlContent = Regex.Replace(htmlContent, "\t", " ");
            htmlContent = Regex.Replace(htmlContent, @">\s+?<", "><");
            htmlContent = Regex.Replace(htmlContent, @"\s{2,}", " ");
            htmlContent = Regex.Replace(htmlContent, " {2,}", @"\s");
            htmlContent = Regex.Replace(htmlContent, @"\s{2,}", @"\s");
            return htmlContent;
        }

        /// <summary>
        /// 无压缩输出
        /// </summary>
        /// <param name="httpTxt"></param>
        /// <param name="cacheByte"></param>
        public static void NoCompressCache(HttpContextBase httpTxt, byte[] cacheByte)
        {
            SetClientCache(httpTxt);
            httpTxt.Response.ContentEncoding = Encoding.UTF8;
            httpTxt.Response.BinaryWrite(cacheByte);
            httpTxt.Response.End();
        }

        /// <summary>
        /// gzip 或 deflate 压缩输出
        /// </summary>
        /// <param name="httpTxt"></param>
        /// <param name="cacheByte"></param>
        /// <param name="isGzip"></param>
        public static void CompressCache(HttpContextBase httpTxt, byte[] cacheByte, bool isGzip)
        {
            Utils.HttpHelper.SetClientCache(httpTxt);
            httpTxt.Response.ContentType = "text/html";
            httpTxt.Response.ContentEncoding = Encoding.UTF8;

            if (true == isGzip)
            {
                httpTxt.Response.AppendHeader("Content-Encoding", "gzip");
            }
            else
            {
                httpTxt.Response.AppendHeader("Content-Encoding", "deflate");
            }

            httpTxt.Response.BinaryWrite(cacheByte);
            httpTxt.Response.Flush();
            httpTxt.Response.End();
        }

        /// <summary>
        /// 设置客户端缓存(http头信息)
        /// </summary>
        /// <param name="httpTxt"></param>
        public static void SetClientCache(HttpContextBase httpTxt)
        {
            // 公开指定是否初客户端或者代理缓存
            httpTxt.Response.Cache.SetCacheability(HttpCacheability.Public);
            //设置缓存器最大时间，指定应答信息多久才再次刷新
            httpTxt.Response.Cache.SetMaxAge(new TimeSpan(1000000000000));
            // 设置资源过期时间
            httpTxt.Response.Cache.SetExpires(DateTime.Now.AddDays(1));
        }

        /// <summary>
        /// 设置客户端缓存(http头信息)
        /// </summary>
        /// <param name="httpTxt"></param>
        public static void SetClientCache(HttpContext httpTxt)
        {
            // 公开指定是否初客户端或者代理缓存
            httpTxt.Response.Cache.SetCacheability(HttpCacheability.Public);
            //设置缓存器最大时间，指定应答信息多久才再次刷新
            httpTxt.Response.Cache.SetMaxAge(new TimeSpan(1000000000000));
            // 设置资源过期时间
            httpTxt.Response.Cache.SetExpires(DateTime.Now.AddDays(1));
        }
    }

}